package com.ztgf.commodity.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ztgf.commodity.common.config.YmlConfig;
import com.ztgf.commodity.mapper.BrandInfoMapper;
import com.ztgf.commodity.models.bo.BrandInfoBO;
import com.ztgf.commodity.models.bo.BrandInfoSaveBO;
import com.ztgf.commodity.models.dto.BrandInfoDTO;
import com.ztgf.commodity.models.dto.CommodityCategoryDTO;
import com.ztgf.commodity.models.dto.CommodityInfoDTO;
import com.ztgf.commodity.models.service.IBrandInfoService;
import com.ztgf.commodity.models.service.ICategoryBrandAttributesRelationService;
import com.ztgf.commodity.models.service.ICommodityCategoryService;
import com.ztgf.commodity.models.service.ICommodityInfoService;
import com.ztgf.commodity.models.vo.*;
import com.ztgf.common.utils.PinYinUtils;
import com.ztgf.shopping.models.dto.shop.ShopBrandRelationAuditDTO;
import com.ztgf.shopping.models.service.shop.IShopBrandRelationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import static com.ztgf.common.utils.UtilConstants.isNull;

/**
 * author: chenyu.wang
 * date: 2020-05-25 13:54
 * Description:
 */
@Slf4j
@DubboService
public class BrandInfoServiceImpl extends ServiceImpl<BrandInfoMapper, BrandInfoDTO> implements IBrandInfoService {

    @Resource
    private YmlConfig ymlConfig;
    @DubboReference
    private ICommodityInfoService commodityInfoService;

    @DubboReference
    private IShopBrandRelationService shopBrandRelationService;

    @DubboReference
    private ICommodityCategoryService commodityCategoryService;

    @DubboReference
    private ICategoryBrandAttributesRelationService categoryBrandAttributesRelationService;

    @Override
    public boolean addBrand(BrandInfoSaveBO saveBO) {
        BrandInfoDTO brandInfoDTO = new BrandInfoDTO();
        BeanUtils.copyProperties(saveBO, brandInfoDTO);
        brandInfoDTO.setInitials(PinYinUtils.getPinYinHeadCharFirstBrand(saveBO.getName()));
        brandInfoDTO.setId(ymlConfig.getPkId());
        return this.insert(brandInfoDTO);
    }

    @Override
    public boolean deleteLogic(Long id) {
        BrandInfoDTO brandInfoDTO = this.selectById(id);
        if (brandInfoDTO != null) {
            if (brandInfoDTO.getStatus().equals(0)) {
                brandInfoDTO.setStatus(1);
                //异步批量下架品牌关联的商品
                commodityInfoService.updateBatchPublish(id);
            } else {
                brandInfoDTO.setStatus(0);
            }
            return this.updateById(brandInfoDTO);
        }
        return false;
    }

    @Override
    public Page<BrandInfoVO> queryPageList(Page<BrandInfoVO> page, BrandInfoBO bo) {
        Wrapper<BrandInfoDTO> wrapper = new EntityWrapper<>();
        if (bo.getName() != null) {
            wrapper.like("name", bo.getName());
        }
        if (bo.getManufacturer() != null) {
            wrapper.like("manufacturer", bo.getManufacturer());
        }
        if (bo.getInitials() != null) {
            wrapper.like("initials", bo.getInitials());
        }
        if (bo.getIsPublish() != null) {
            wrapper.eq("is_publish", bo.getIsPublish());
        }
        if (bo.getStatus() != null) {
            wrapper.eq("status", bo.getStatus());
        }
        if (bo.getStartDate() != null) {
            wrapper.ge("create_time", bo.getStartDate());
        }
        if (bo.getEndDate() != null) {
            wrapper.le("create_time", bo.getEndDate());
        }

        wrapper.orderBy("sort", true); //默认升序

        Page<BrandInfoDTO> pagedto = new Page<>(bo.getPageNo(), bo.getPageSize());
        pagedto = this.selectPage(pagedto, wrapper);
        page.setTotal(pagedto.getTotal());
        page.setSize(pagedto.getSize());
        ArrayList<BrandInfoVO> vos = new ArrayList<BrandInfoVO>();
        List<BrandInfoDTO> brandInfoDTOList = pagedto.getRecords();
        for (BrandInfoDTO dto : brandInfoDTOList) {
            BrandInfoVO vo = new BrandInfoVO();
            BeanUtils.copyProperties(dto, vo);
            vo.setShopNumber(shopBrandRelationService.getShopCount(dto.getId()));
            vos.add(vo);
        }

        page.setRecords(vos);
        return page;
    }

    @Override
    public List<CommodityShopBrandVO> queryShopBrandList(Long shopId) {
        return baseMapper.queryShopBrandList(shopId);
    }

    @Override
    public List<CommodityShopBrandVO> queryShopBrandListByShopIdAndBrandId(Long shopId,Long brandId) {
        return baseMapper.queryShopBrandListByShopIdAndBrandId(shopId,brandId);
    }


    @Override
    public BrandInfoDTO getByName(String name) {
        Wrapper<BrandInfoDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("name", name);
        wrapper.last("limit 1");

        return this.selectOne(wrapper);
    }

    @Override
    public boolean updateByName(String name) {
        Wrapper<BrandInfoDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("name", name);

        BrandInfoDTO dto = new BrandInfoDTO();
        dto.setName(name);

        return this.update(dto, wrapper);
    }

    @Override
    public List<BrandInfoDTO> queryList(String initials, Long shopId) {
        return baseMapper.queryList(initials, shopId);
    }

    /**
     * @Description: 导入时根据品牌名称判断是否存在品牌，有则返回，没有则新建
     * @Author: chenyu.wang
     * @Params: [brandName]
     * @Date: 2020.11.24 17:07
     */
    @Override
    public CategoryBrandVO checkBrand(String brandName) {
        Wrapper<BrandInfoDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("name", brandName);
        BrandInfoDTO dto = this.selectOne(wrapper);
        if (null != dto) {
            CategoryBrandVO vo = new CategoryBrandVO();
            vo.setBrandId(dto.getId());
            vo.setBrandName(dto.getName());
            vo.setNotes(dto.getNotes());
            return vo;
        }
        Long id = ymlConfig.getPkId();
        BrandInfoDTO insertDto = new BrandInfoDTO();
        insertDto.setName(brandName);
        insertDto.setInitials(PinYinUtils.getPinYinHeadCharFirstBrand(brandName));
        insertDto.setStatus(0);
        insertDto.setIsPublish(1);
        insertDto.setNotes("导入属性时新增的品牌");
        insertDto.setId(id);
        boolean insert = this.insert(insertDto);
        if (!insert) {
            throw new RuntimeException("导入新增品牌失败!");
        }
        CategoryBrandVO vo = new CategoryBrandVO();
        vo.setBrandId(id);
        vo.setBrandName(brandName);
        return vo;
    }

    @Override
    public List<BrandInfoDTO> queryBrandByCategoryId(Long categoryId) {
        log.info("queryBrandByCategoryId的类目id : {}", categoryId);
        List<BrandInfoDTO> tureList = new ArrayList<>();
        if (null == categoryId) {
            log.info("queryBrandByCategoryId的类目id为空 : {}", categoryId);
            // 查询所有品牌
            Wrapper<BrandInfoDTO> wrapper = new EntityWrapper<>();
            wrapper.eq("status", 0).eq("is_publish", 1);
            List<BrandInfoDTO> brandInfoDTOS = this.selectList(wrapper);
            if (isNull(brandInfoDTOS)) {
                return null;
            }
            for (BrandInfoDTO brandInfoDTO : brandInfoDTOS) {
                Wrapper<CommodityInfoDTO> wrapper2 = new EntityWrapper<>();
                wrapper2.eq("brand_id", brandInfoDTO.getId());
                wrapper2.eq("audit_status", 1);
                wrapper2.eq("is_publish", 1);
                wrapper2.eq("status", 0);
                List<CommodityInfoDTO> goodsList = commodityInfoService.selectList(wrapper2);
                if (isNull(goodsList)) {
                    continue;
                }
                tureList.add(brandInfoDTO);
            }
            return tureList;
        }
        List<CategoryBrandAttributesVO> list = categoryBrandAttributesRelationService.queryByCategoryId(categoryId);
        if (!isNull(list)) {
            for (CategoryBrandAttributesVO vo : list) {
                Wrapper<CommodityInfoDTO> wrapper = new EntityWrapper<>();
                wrapper.eq("brand_id", vo.getId());
                wrapper.eq("audit_status", 1);
                wrapper.eq("is_publish", 1);
                wrapper.eq("status", 0);
                wrapper.eq("category_id", categoryId);
                List<CommodityInfoDTO> goodsList = commodityInfoService.selectList(wrapper);
                if (isNull(goodsList)) {
                    continue;
                }
                BrandInfoDTO dto = new BrandInfoDTO();
                dto.setId(vo.getId());
                dto.setName(vo.getAttributesName());
                tureList.add(dto);
            }
            return tureList;
        }
        Wrapper<CommodityCategoryDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("parent_id", categoryId);
        List<CommodityCategoryDTO> selectList = commodityCategoryService.selectList(wrapper);
        if (isNull(selectList)) {
            return null;
        }
        List<CommodityCategoryDTO> list2 = new ArrayList<>();
        List<CommodityCategoryDTO> finalCategory = commodityCategoryService.getAllFinalCategory(selectList, list2);
        if (isNull(finalCategory)) {
            return null;
        }
        HashSet<Long> set = new HashSet<>();
        for (CommodityCategoryDTO dto : finalCategory) {
            List<CategoryBrandAttributesVO> list3 = categoryBrandAttributesRelationService.queryByCategoryId(dto.getId());
            if (isNull(list3)) {
                continue;
            }
            for (CategoryBrandAttributesVO attributesVO : list3) {
                boolean add = set.add(attributesVO.getId());
                if (!add) {
                    continue;
                }
                Wrapper<CommodityInfoDTO> wrapper2 = new EntityWrapper<>();
                wrapper2.eq("brand_id", attributesVO.getId());
                wrapper2.eq("audit_status", 1);
                wrapper2.eq("is_publish", 1);
                wrapper2.eq("status", 0);
                wrapper2.eq("category_id", dto.getId());
                List<CommodityInfoDTO> goodsList = commodityInfoService.selectList(wrapper2);
                if (isNull(goodsList)) {
                    continue;
                }
                BrandInfoDTO dto2 = new BrandInfoDTO();
                dto2.setId(attributesVO.getId());
                dto2.setName(attributesVO.getAttributesName());
                tureList.add(dto2);
            }
        }
        return tureList;
    }

    @Override
    public List<CategoryBrandVO> getImportDate(List<CategoryBrandVO> brandNames, List<CategoryBrandVO> brandList, CategoryAdminDetailsNewVO category) {
        for (CategoryBrandVO brandName : brandNames) {
            CategoryBrandVO brandVO = this.checkBrand(brandName.getBrandName());
            brandName.setBrandName(brandVO.getBrandName());
            brandName.setBrandId(brandVO.getBrandId());
            brandName.setNotes(brandVO.getNotes());
            log.info("去重后的品牌:{}", brandName.getBrandName());
            List<String> unitName = new ArrayList<>();
            List<Long> params = new ArrayList<>();
            List<Long> seal = new ArrayList<>();
            HashSet<Long> set = new HashSet<>();
            for (CategoryBrandVO vo : brandList) {
                if (vo.getBrandName().equals(brandName.getBrandName())) {
                    log.info("处理品牌属性");
                    // 处理单位
                    for (CategoryBrandAttributesVO voUnitId : vo.getUnitIds()) {
                        if (!unitName.contains(voUnitId.getAttributesName())) {
                            unitName.add(voUnitId.getAttributesName());
                            CategoryBrandAttributesVO unit = commodityCategoryService.checkUnit(voUnitId.getAttributesName());
                            brandName.getUnitIds().add(unit);
                        }
                    }
                    // 处理参数属性
                    List<CategoryBrandAttributesVO> list = commodityCategoryService.checkParameterAttributes(vo.getParamIds(), category, brandName);
                    for (CategoryBrandAttributesVO categoryBrandAttributesVO : list) {
                        if (!params.contains(categoryBrandAttributesVO.getId())) {
                            params.add(categoryBrandAttributesVO.getId());
                            brandName.getParamIds().add(categoryBrandAttributesVO);
                        }
                    }
                    // 处理规格属性
                    List<CategoryBrandAttributesVO> specificationAttributes = commodityCategoryService.checkSpecificationAttributes(vo.getSpecificationIds(), category, brandName);
                    for (CategoryBrandAttributesVO specificationAttribute : specificationAttributes) {
                        if (!seal.contains(specificationAttribute.getId())) {
                            seal.add(specificationAttribute.getId());
                            brandName.getSpecificationIds().add(specificationAttribute);
                        }
                    }
                    // 处理标签
                    if (!isNull(vo.getLabelList())) {
                        for (CategoryBrandAttributesVO categoryBrandAttributesVO : vo.getLabelList()) {
                            CategoryBrandAttributesVO checkLabel = commodityCategoryService.checkLabel(categoryBrandAttributesVO.getAttributesName());
                            boolean add = set.add(checkLabel.getId());
                            if (!add) {
                                continue;
                            }
                            brandName.getLabelList().add(checkLabel);
                        }
                    }
                }
            }
        }
        return brandNames;
    }



    @Override
    public CategoryAdminDetailsNewVO importAttributes(byte[] input, Long id) {
        // 先查询类目
        CategoryAdminDetailsNewVO details = commodityCategoryService.queryCategoryDetails(id);
        if (null == details) {
            return null;
        }
        CategoryAdminDetailsNewVO newVO = new CategoryAdminDetailsNewVO();
        newVO.setId(details.getId());
        newVO.setCategoryName(details.getCategoryName());
        newVO.setSort(details.getSort());
        newVO.setIsDisplayNavBar(details.getIsDisplayNavBar());
        newVO.setParentId(details.getParentId());
        if (!isNull(details.getFilterList())) {
            newVO.setFilterList(details.getFilterList());
        }
        // 解析excel
        // 将文件byte转成inputStream
        ByteArrayInputStream inputStream = new ByteArrayInputStream(input);
        try {
            Workbook workbook = WorkbookFactory.create(inputStream);
            inputStream.close();
            // 获取工作表对象
            Sheet sheet = workbook.getSheetAt(0);
            // 获取Excel表格中数据的行数
            int totalRow = sheet.getPhysicalNumberOfRows();
            // 获取Excel表格中数据的列数
            int totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
            // 第一行
            Row oneRow = sheet.getRow(0);
            // 所有数据
            List<CategoryBrandVO> brandList = new ArrayList<>();
            List<String> name = new ArrayList<>();
            // 相同品牌的数据过滤
            List<CategoryBrandVO> brandNames = new ArrayList<>();
            for (int i = 1; i <= totalRow; i++) {
                // 行
                Row row = sheet.getRow(i);
                // 若有空行继续下一行（因为EXCEL有空行时报错故加上此代码）
                if (null == row || "".equals(row)) {
                    totalRow--;
                    continue;
                }
                String check = this.getCellValue(row.getCell(0));
                if (!StringUtils.isNotBlank(check)) {
                    totalRow--;
                    continue;
                }
                CategoryBrandVO brandVO = new CategoryBrandVO();
                CategoryBrandVO names = new CategoryBrandVO();
                List<CategoryBrandAttributesVO> salesAttributes = new ArrayList<>();
                List<CategoryBrandAttributesVO> unitAttributes = new ArrayList<>();
                List<CategoryBrandAttributesVO> parameterAttributes = new ArrayList<>();
                List<CategoryBrandAttributesVO> labels = new ArrayList<>();
                String brandName = this.getCellValue(row.getCell(4));
                for (int j = 4; j <= totalCells; j++) {
                    String value = this.getCellValue(row.getCell(j));
                    if (StringUtils.isBlank(value)) {
                        continue;
                    }
                    // 获取标题
                    String title = this.getCellValue(oneRow.getCell(j));
                    if (title.contains("销售属性")) {
                        CategoryBrandAttributesVO bean = new CategoryBrandAttributesVO();
                        String[] split = value.split("！");
                        bean.setAttributesName(split[0]);
                        bean.setNotes(split[1]);
                        salesAttributes.add(bean);
                    }
                    if (title.contains("参数属性")) {
                        CategoryBrandAttributesVO bean = new CategoryBrandAttributesVO();
                        String[] split = value.split("！");
                        bean.setAttributesName(split[0]);
                        bean.setNotes(split[1]);
                        parameterAttributes.add(bean);
                    }
                    if (title.contains("销售单位")) {
                        CategoryBrandAttributesVO testBean = new CategoryBrandAttributesVO();
                        testBean.setAttributesName(value);
                        unitAttributes.add(testBean);
                    }
                    if (title.contains("标签属性")) {
                        CategoryBrandAttributesVO testBean = new CategoryBrandAttributesVO();
                        testBean.setAttributesName(value);
                        labels.add(testBean);
                    }
                }
                brandVO.setBrandName(brandName);
                brandVO.setUnitIds(unitAttributes);
                brandVO.setSpecificationIds(salesAttributes);
                brandVO.setParamIds(parameterAttributes);
                brandVO.setLabelList(labels);
                brandList.add(brandVO);
                boolean contains = name.contains(brandName);
                if (!contains) {
                    names.setBrandName(brandName);
                    names.setUnitIds(new ArrayList<>());
                    names.setParamIds(new ArrayList<>());
                    names.setSpecificationIds(new ArrayList<>());
                    names.setLabelList(new ArrayList<>());
                    brandNames.add(names);
                    name.add(brandName);
                }
            }
            List<CategoryBrandVO> importDate = this.getImportDate(brandNames, brandList, newVO);
            newVO.setBrandList(importDate);
            return newVO;
        } catch (Exception e) {
            log.info("属性导入错误信息:{}", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Description: 获取excel数据时对数据类型的判定及处理
     * @Author: chenyu.wang
     * @Params: [cell]
     * @Date: 2020.11.24 11:20
     */
    private String getCellValue(Cell cell) {
        String cellValue = "";
        if (cell == null) {
            return cellValue;
        }
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                cellValue = cell.getStringCellValue().trim();
                break;
            case Cell.CELL_TYPE_NUMERIC:
                DecimalFormat df = new DecimalFormat("0");

                cellValue = df.format(cell.getNumericCellValue());
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_FORMULA:
                cellValue = cell.getCellFormula();
                break;
            default:
                cellValue = "";
        }
        return cellValue;
    }
}
